<template>
    <!-- 配置页面 -->
    <div class="config">
        <card-pane>
            <template v-slot:title>
                <span class="label">
                    <svg-icon
                        icon-class="font-layout-2-fill"
                        class="font-layout-2-fill"
                    />
                    <span class="text">基础设置</span>
                </span>
            </template>
            <template v-slot:list>
                <div class="list">
                    <base-form
                        :formItems="formItems"
                        :formConfig="formConfig"
                        :formData="formSubmit"
                        :formRules="formRule"
                        ref="searchForm"
                    >
                        <template
                            v-slot:pickerOptions="slotProps"
                            v-if="formSubmit.type === 'select'"
                        >
                            <div class="option-contener">
                                <el-form-item>
                                    <el-divider
                                        >{{ slotProps.childItem.label }}
                                    </el-divider>
                                </el-form-item>
                                <el-form-item label="开始时间">
                                    <el-time-select
                                        v-model="
                                            slotProps.childItem.options.start
                                        "
                                        @change="handelTimePickerChange"
                                        :picker-options="{
                                            start: '00:00',
                                            step: '00:01',
                                            end: '23:59'
                                        }"
                                        placeholder="开始时间"
                                    />
                                </el-form-item>
                                <el-form-item label="结束时间">
                                    <el-time-select
                                        v-model="
                                            slotProps.childItem.options.end
                                        "
                                        @change="handelTimePickerChange"
                                        :picker-options="{
                                            start: '00:00',
                                            step: '00:01',
                                            end: '23:59'
                                        }"
                                        placeholder="结束时间"
                                    />
                                </el-form-item>
                                <el-form-item label="时间间隔">
                                    <el-time-select
                                        v-model="
                                            slotProps.childItem.options.step
                                        "
                                        @change="handelTimePickerChange"
                                        :picker-options="{
                                            start: '00:00',
                                            step: '00:01',
                                            end: '00:59'
                                        }"
                                        placeholder="时间间隔"
                                    />
                                </el-form-item>
                                <el-form-item label="最小时间">
                                    <el-time-select
                                        v-model="
                                            slotProps.childItem.options.minTime
                                        "
                                        @change="handelTimePickerChange"
                                        :picker-options="{
                                            start: '00:00',
                                            step: '00:01',
                                            end: '23:59'
                                        }"
                                        placeholder="最小时间"
                                    />
                                </el-form-item>
                                <el-form-item label="最大时间">
                                    <el-time-select
                                        v-model="
                                            slotProps.childItem.options.maxTime
                                        "
                                        @change="handelTimePickerChange"
                                        :picker-options="{
                                            start: '00:00',
                                            step: '00:01',
                                            end: '23:59'
                                        }"
                                        placeholder="最大时间"
                                    />
                                </el-form-item>
                            </div>
                        </template>
                    </base-form>
                </div>
            </template>
        </card-pane>
        <card-pane>
            <template v-slot:title>
                <span class="label">
                    <svg-icon
                        icon-class="font-layout-2-fill"
                        class="font-layout-2-fill"
                    />
                    <span class="text">规则项设置</span>
                </span>
            </template>
            <template v-slot:list>
                <div class="list">
                    <base-form
                        :formItems="ruleItems"
                        :formConfig="ruleConfig"
                        :formData="ruleSubmit"
                        ref="searchForm"
                    >
                        <template slot="customRule">
                            <el-form-item
                                class="menu-icon"
                                label="自定义规则项"
                            >
                                <el-button
                                    type="primary"
                                    @click="handelOpenCestomRule"
                                    >自定义编码</el-button
                                >
                            </el-form-item>
                        </template>
                    </base-form>
                </div>
            </template>
        </card-pane>
        <!-- 预览弹框 -->
        <el-dialog
            title="自定义规则项"
            :visible.sync="cestomRule"
            width="60%"
            v-dialogDrag
            append-to-body
            :close-on-click-modal="false"
            :close-on-press-escape="false"
        >
            <div class="edit-rule-contener">
                <monaco-editor
                    :editorOptions="editorOptions"
                    @onCodeChange="cesiumRuleEditChange"
                />
            </div>
            <!-- 新增 -->
            <span slot="footer" class="dialog-footer">
                <el-button size="small" @click="handelCloseCestomRule"
                    >取 消</el-button
                >
                <el-button
                    size="small"
                    type="primary"
                    @click="handelConfirmCestomRule"
                    >确 认</el-button
                >
            </span>
        </el-dialog>
    </div>
</template>
<script>
import BaseForm from '@/components/baseForm/index.vue'
import CardPane from '../../base/components/cardPane'
import MonacoEditor from '@/components/monacoEditor/index'
import { ruleOptions } from '../baseSetting/rules'
import { setFormItemProp } from '@/utils/tool'
export default {
    components: {
        BaseForm,
        CardPane,
        MonacoEditor
    },
    props: {
        curryCom: {
            type: Object,
            default: () => {
                return {}
            }
        }
    },
    watch: {
        curryCom: {
            handler: async function(newVal) {
                if (
                    JSON.stringify(newVal) !== '{}' &&
                    JSON.stringify(newVal.value) !== '{}'
                ) {
                    await this.copyCol()
                    this.activeCol = newVal
                    this.generateFormItems(newVal)
                } else {
                    await this.copyCol()
                    return
                }
            },
            deep: true,
            immediate: true
        },
        ruleSubmit: {
            handler: function(newVal) {
                if (JSON.stringify(newVal) !== '{}') {
                    this.$bus.$emit('RulesChange')
                } else {
                    return
                }
            },
            deep: true
        }
    },
    data() {
        return {
            // 选中的列
            activeCol: {},
            // 配置表单的表单项列表
            formItems: [
                [
                    {
                        ltype: 'input',
                        placeholder: '请输入绑定的字段值',
                        label: '字段值',
                        prop: 'prop',
                        width: 'w-1',
                        clearable: true,
                        isShow: false,
                        question: '表单的key值，唯一名称'
                    }
                ],
                [
                    {
                        ltype: 'input',
                        placeholder: '请输入label文字',
                        label: 'label',
                        prop: 'label',
                        width: 'w-1',
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'select',
                        placeholder: '请选择控件宽度',
                        label: '宽度',
                        options: [
                            {
                                label: '自动',
                                value: 'w-auto'
                            },
                            {
                                label: '一份',
                                value: 'w-1'
                            },
                            {
                                label: '两份',
                                value: 'w-2'
                            },
                            {
                                label: '三份',
                                value: 'w-3'
                            },
                            {
                                label: '四份',
                                value: 'w-4'
                            },
                            {
                                label: '五份',
                                value: 'w-5'
                            },
                            {
                                label: '六份',
                                value: 'w-6'
                            },
                            {
                                label: '七份',
                                value: 'w-7'
                            },
                            {
                                label: '八份',
                                value: 'w-8'
                            },
                            {
                                label: '九份',
                                value: 'w-9'
                            }
                        ],
                        prop: 'width',
                        width: 'w-1',
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'input',
                        placeholder: '请输入输入提示语',
                        label: '提示语',
                        prop: 'placeholder',
                        width: 'w-1',
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'switch',
                        label: '禁用',
                        prop: 'disabled',
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'switch',
                        label: '可清空',
                        prop: 'clearable',
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'switch',
                        label: '只读',
                        prop: 'readonly',
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'switch',
                        label: '可输入',
                        prop: 'editable',
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'select',
                        placeholder: '请选择输入框中的格式',
                        label: '输入框格式',
                        prop: 'format',
                        width: 'w-1',
                        options: [],
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'select',
                        placeholder: '请选择绑定值的格式',
                        label: '绑定值格式',
                        prop: 'valueFormat',
                        width: 'w-1',
                        options: [],
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'input',
                        placeholder: '选择范围时的分割符',
                        label: '范围分割符',
                        prop: 'rangeSeparator',
                        width: 'w-1',
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'input',
                        placeholder: '开始时间占位内容',
                        label: '开始占位内容',
                        prop: 'startPlaceholder',
                        width: 'w-1',
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'input',
                        placeholder: '结束时间占位内容',
                        label: '结束占位内容',
                        prop: 'endPlaceholder',
                        width: 'w-1',
                        clearable: true,
                        isShow: false
                    }
                ],
                [
                    {
                        ltype: 'custom',
                        slotName: 'pickerOptions',
                        placeholder: '选择器选项',
                        label: '选择器选项',
                        prop: 'pickerOptions',
                        width: 'w-1',
                        isShow: false,
                        prefixIcon: 'search',
                        options: {}
                    }
                ]
            ],
            // 表单配置项
            formConfig: {
                labelPosition: 'left', // label对齐方式
                labelWidth: '100px',
                size: 'mini'
            },
            // 表单规则
            formRule: {
                prop: [
                    {
                        required: true,
                        message: '请输入唯一值',
                        trigger: 'blur'
                    }
                ]
            },
            // 表单提交项
            formSubmit: {},
            // 头部图标选择框是否显示
            prefixIconIconSelectVisible: false,
            // 尾部图标选择框是否显示
            suffixIconIconSelectVisible: false,
            // 规则表单项
            ruleItems: [
                [
                    {
                        ltype: 'switch',
                        label: '是否必填',
                        prop: 'required',
                        isShow: true
                    }
                ],
                [
                    {
                        ltype: 'input',
                        placeholder: '请输入必填校验提示',
                        label: '必填校验提示',
                        prop: 'message',
                        width: 'w-1',
                        clearable: true,
                        isShow: true
                    }
                ],
                [
                    {
                        ltype: 'select',
                        placeholder: '请选择其它校验',
                        label: '其它校验',
                        options: ruleOptions,
                        prop: 'validator',
                        width: 'w-1',
                        clearable: true,
                        isShow: true
                    }
                ],
                [
                    {
                        ltype: 'custom',
                        slotName: 'customRule',
                        placeholder: '自定义规则项',
                        label: '自定义规则项',
                        prop: 'customRule',
                        width: 'w-1',
                        isShow: true,
                        prefixIcon: 'search'
                    }
                ]
            ],
            // 规则表单配置项
            ruleConfig: {
                labelPosition: 'left', // label对齐方式
                labelWidth: '100px',
                size: 'mini'
            },
            // 规则表单提交项
            ruleSubmit: {
                required: false,
                message: '',
                validator: ''
            },
            // 自定义规则项
            cestomRule: false,
            cestomRuleValue: '',
            editorOptions: {
                value: `
					function fn(rule, value, callback){
						if (value) {
							var reg = /*请输入您要自定义的正则*/
							if (reg.test(value) === false) {
								callback(new Error('/*请输入验证不通过的提示*/'))
							} else {
								callback()
							}
						} else {
							callback()
						}
					}
				`,
                language: 'js'
            }
        }
    },
    methods: {
        copyCol() {
            return new Promise((resove, reject) => {
                try {
                    this.formItems.forEach(ele => {
                        if (ele.length > 0) {
                            ele.forEach(element => {
                                this.formItems = setFormItemProp(
                                    this.formItems,
                                    element.prop,
                                    'isShow',
                                    false
                                )
                            })
                        }
                    })
                    this.formSubmit = {}
                    this.activeCol = {}
                    resove(true)
                } catch (error) {
                    reject(error)
                }
            })
        },
        /**
         * 生成动态表单项
         */
        async generateFormItems(config) {
            if (config.value && JSON.stringify(config.value) !== '{}') {
                this.formSubmit = config.value
                let curryType = this.formSubmit.type
                this.formItems.forEach(element => {
                    element.forEach(ele => {
                        if (ele.prop === 'format') {
                            ele.options = this.generateFormartOptions(curryType)
                        } else if (ele.prop === 'valueFormat') {
                            ele.options = this.generateValueFormartOptions(
                                curryType
                            )
                        }
                        if (ele.prop === 'pickerOptions') {
                            ele.options = this.formSubmit.pickerOptions
                        }
                    })
                })
                for (const key in config.value) {
                    if (Object.hasOwnProperty.call(config.value, key)) {
                        this.formItems = setFormItemProp(
                            this.formItems,
                            key,
                            'isShow',
                            true
                        )
                    }
                }
            }
            if (config.rule && JSON.stringify(config.rule) !== '{}') {
                this.ruleSubmit = config.rule
            }
        },
        /**
         * 打开规则自定义弹框
         */
        handelOpenCestomRule() {
            this.cestomRule = true
        },
        /**
         * 确认自定义的规则
         */
        handelConfirmCestomRule() {
            try {
                // 将代码编辑器中编辑的内容转换为可执行的代码
                const paramsAndBody = this.cestomRuleValue
                    .replace(
                        /function\s*\w*\s*\((.*?)\)\s*{([\s\S]*)}/,
                        '$1|$2'
                    )
                    .split('|')
                const params = paramsAndBody[0]
                const body = paramsAndBody[1]
                this.ruleSubmit.validator = new Function(params, body)
            } catch (error) {
                throw new Error(error)
            }
            this.cestomRule = false
        },
        /**
         * 取消自定义的规则
         */
        handelCloseCestomRule() {
            this.cestomRule = false
        },
        /**
         * 自定义规则项变化
         */
        cesiumRuleEditChange(val) {
            this.cestomRuleValue = val
        },
        /**
         * 生成类型对应的显示格式下拉选项
         */
        generateFormartOptions(type) {
            const datas = {
                date: [
                    {
                        label: 'yyyy-MM-dd',
                        value: 'yyyy-MM-dd'
                    },
                    {
                        label: 'yyyy-M-d',
                        value: 'yyyy-M-d'
                    }
                ],
                dates: [
                    {
                        label: 'yyyy-MM-dd',
                        value: 'yyyy-MM-dd'
                    },
                    {
                        label: 'yyyy-M-d',
                        value: 'yyyy-M-d'
                    }
                ],
                daterange: [
                    {
                        label: 'yyyy-MM-dd',
                        value: 'yyyy-MM-dd'
                    },
                    {
                        label: 'yyyy-M-d',
                        value: 'yyyy-M-d'
                    }
                ],
                month: [
                    {
                        label: 'MM',
                        value: 'MM'
                    },
                    {
                        label: 'M',
                        value: 'M'
                    }
                ],
                months: [
                    {
                        label: 'MM',
                        value: 'MM'
                    },
                    {
                        label: 'M',
                        value: 'M'
                    }
                ],
                monthrange: [
                    {
                        label: 'MM',
                        value: 'MM'
                    },
                    {
                        label: 'M',
                        value: 'M'
                    }
                ],
                year: [
                    {
                        label: 'yyyy',
                        value: 'yyyy'
                    }
                ],
                years: [
                    {
                        label: 'yyyy',
                        value: 'yyyy'
                    }
                ],
                datetimerange: [
                    {
                        label: 'yyyy-MM-dd HH:mm:ss',
                        value: 'yyyy-MM-dd HH:mm:ss'
                    },
                    {
                        label: 'yyyy-M-d HH:mm:ss',
                        value: 'yyyy-M-d HH:mm:ss'
                    },
                    {
                        label: 'AM/PM',
                        value: 'AM/PM'
                    },
                    {
                        label: 'am/pm',
                        value: 'am/pm'
                    }
                ],
                week: [
                    {
                        label: 'yyyy 第 WW 周',
                        value: 'yyyy 第 WW 周'
                    }
                ]
            }
            return datas[type]
        },
        /**
         * 生成类型对应的数据格式下拉选项
         */
        generateValueFormartOptions(type) {
            const datas = {
                date: [
                    {
                        label: 'yyyy-MM-dd',
                        value: 'yyyy-MM-dd'
                    },
                    {
                        label: 'yyyy-M-d',
                        value: 'yyyy-M-d'
                    },
                    {
                        label: '时间戳',
                        value: 'timestamp'
                    }
                ],
                dates: [
                    {
                        label: 'yyyy-MM-dd',
                        value: 'yyyy-MM-dd'
                    },
                    {
                        label: 'yyyy-M-d',
                        value: 'yyyy-M-d'
                    },
                    {
                        label: '时间戳',
                        value: 'timestamp'
                    }
                ],
                daterange: [
                    {
                        label: 'yyyy-MM-dd',
                        value: 'yyyy-MM-dd'
                    },
                    {
                        label: 'yyyy-M-d',
                        value: 'yyyy-M-d'
                    },
                    {
                        label: '时间戳',
                        value: 'timestamp'
                    }
                ],
                month: [
                    {
                        label: 'MM',
                        value: 'MM'
                    },
                    {
                        label: 'M',
                        value: 'M'
                    }
                ],
                months: [
                    {
                        label: 'MM',
                        value: 'MM'
                    },
                    {
                        label: 'M',
                        value: 'M'
                    }
                ],
                monthrange: [
                    {
                        label: 'MM',
                        value: 'MM'
                    },
                    {
                        label: 'M',
                        value: 'M'
                    }
                ],
                year: [
                    {
                        label: 'yyyy',
                        value: 'yyyy'
                    },
                    {
                        label: '时间戳',
                        value: 'timestamp'
                    }
                ],
                years: [
                    {
                        label: 'yyyy',
                        value: 'yyyy'
                    },
                    {
                        label: '时间戳',
                        value: 'timestamp'
                    }
                ],
                datetimerange: [
                    {
                        label: 'yyyy-MM-dd HH:mm:ss',
                        value: 'yyyy-MM-dd HH:mm:ss'
                    },
                    {
                        label: 'yyyy-M-d HH:mm:ss',
                        value: 'yyyy-M-d HH:mm:ss'
                    },
                    {
                        label: '时间戳',
                        value: 'timestamp'
                    }
                ]
            }
            return datas[type]
        },
        /**
         * 时间选择器改变
         */
        handelTimePickerChange() {
            this.formItems.forEach(ele => {
                ele.forEach(element => {
                    if (element.prop === 'pickerOptions') {
                        this.formSubmit.pickerOptions = element.options
                    }
                })
            })
        }
    }
}
</script>
<style lang="scss">
.edit-rule-contener {
    @include box_flex(
        $width: 100%,
        $height: 60vh,
        $direction: column,
        $justify: flex-start,
        $align: flex-start
    );
}
</style>
<style lang="scss" scoped>
.config {
    @include box_flex(
        $width: 100%,
        $height: 100%,
        $direction: column,
        $justify: flex-start,
        $align: flex-start
    );

    overflow-y: auto;
    .list {
        padding: $margin-sm;
        .option-contener {
            @include box_flex(
                $width: 100%,
                $height: auto,
                $direction: column,
                $justify: flex-start,
                $align: flex-start
            );
            .option-label {
                font-size: 12px;
            }
        }
    }
}
</style>
